﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using MediaRecommender.Model;
using MediaRecommender.Controller;

namespace MediaRecommender
{
    public class Global : System.Web.HttpApplication
    {

        protected void Application_Start(object sender, EventArgs e)
        {
            Deserialize();

            MediaData md = new MediaData();
            string date = Convert.ToString(DateTime.Now);
           
            //md.getMovieListByGenreId(22, false, false);
            //md.getGamesByPlatformId(4919, "Sony Playstation 4");
            //md.GetBooksByGenre("fantasy");
/*
            GenerateTestUsers(new Random(DateTime.Now.Millisecond));
            
            UserRegistrationController UserReg = new UserRegistrationController();
            User m = new User("Hans", "123456", DateTime.Now, Sex.Male, new List<int>());
            UserReg.AddUserToDatabase(m);
            */
            
        }


        protected void GenerateTestUsers(Random rnd)
        {
            int numberOfUsers = 250;
            List<string> names = new List<string>(); //List to contain unique names
            string baseName = "Joe"; //base name to add to unque modifier to make it easier to identify it as a name
            string dummyPassword = "123456"; //every user needs to have a password, passwords dont need to be unique
            List<int> genres = new List<int>(); //List to contain evenly distrubted genre preferences. 
            //We are going to use the Random() function from the .net framework because pseudorandom numbers are based on the evenly distrubtion principle 
            //and should statistically give us users with enough different prefs to test our algorithm.
            int mediaCounter = 0;

            //generate *numberOfUsers* unique names
            for (int i = 0; i < numberOfUsers; i++)
            {
                names.Add(baseName + Convert.ToString(i));
            }

            //add the users to database and generate media lists with appropriate media
            for (int i = 0; i < numberOfUsers; i++)
            {
                WriteToLog.WriteLog("Got to Joe" + Convert.ToString(i));
                genres = new List<int>();
                genres = GenerateTestGenres(rnd);
                User u = new User(names[i], dummyPassword, DateTime.Now, Sex.Male, genres);
                GenerateTestMediaList(u, genres, rnd.Next(5, 45), rnd);
                WriteToLog.WriteLog("He had " + u.MediaList.Count + " medias in his list");
                WriteToLog.WriteLog("Total media is at: " + Convert.ToString(mediaCounter += u.MediaList.Count));
                UserCollection.Instance.Add(u);
            }
            List<User> lsad = UserCollection.Instance.GetAllUsers();



        }

        private void GenerateTestMediaList(User u, List<int> prefsList, int numberOfMedias, Random rnd)
        {
            List<Media> mediaListToPickFrom = new List<Media>();
            //populate mediaListToPickFrom
            foreach (int i in prefsList)
                mediaListToPickFrom.AddRange(MediaCollection.Instance.GetMedia(x => x.Genres.Contains(i)));
            int currMediaPosition;
            for (int i = 0; i < numberOfMedias; i++)
            {
                currMediaPosition = rnd.Next(0, mediaListToPickFrom.Count);
                try
                {
                    if (!u.MediaList.ContainsKey(mediaListToPickFrom[currMediaPosition]))
                        u.MediaList.Add(mediaListToPickFrom[currMediaPosition], rnd.Next(0, 10));
                }
                catch (ArgumentOutOfRangeException e) { string eC = e.Message; }
            }
        }

        private List<int> GenerateTestGenres(Random rnd)
        {
            List<int> genres = new List<int>();


            //first determain how many prefs this users is going to have
            int count = rnd.Next(3, 25);


            //add *count* different genres to the users list
            int currGenre;
            for (int i = 0; i < count; i++)
            {
                currGenre = rnd.Next(0, 38);
                if (!genres.Contains(currGenre))
                {
                    genres.Add(currGenre);
                }
            }

            return genres;

        }



        protected void Session_Start(object sender, EventArgs e)
        {

        }

        protected void Application_BeginRequest(object sender, EventArgs e)
        {

        }

        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {

        }

        protected void Application_Error(object sender, EventArgs e)
        {
            Serialize();
        }

        protected void Session_End(object sender, EventArgs e)
        {

        }

        protected void Application_End(object sender, EventArgs e)
        {
            Serialize();
        }

        protected void Serialize()
        {
            UserRegistrationController UserCon = new UserRegistrationController();
            MediaController MediaCon = new MediaController();
            
            MediaCon.WriteDbToFile();
            UserCon.WriteUserDbToFile();
        }

        protected void Deserialize()
        {
            UserRegistrationController UserCon = new UserRegistrationController();
            MediaController MediaCon = new MediaController();

            UserCon.ReadUserDbFromFile();
            MediaCon.ReadDbFromFile();
        }
    }
}